using System;
using System.Collections.Generic;
using System.Text;
using NBusiness.Query;

namespace NBusiness.MySql.Query
{
    public enum MySqlBooleanOperator
    {
        Equal,
        NotEqual,
        LessThan,
        LessThanOrEqual,
        GreaterThan,
        GreaterThanOrEqual,
        Like,
        NotLike,
        And,
        Or,
        In,
        NotIn
    }
        
    public abstract class MySqlBoolean : IExpression
    {
        #region Member fields and properties
        private IEvaluatable _left;

        private IEvaluatable _right;

        private MySqlBooleanOperator _operator;
        protected MySqlBooleanOperator Operator
        {
            get { return _operator; }
            set { _operator = value; }
        }
        #endregion

        #region Constructors
        public MySqlBoolean(MySqlBooleanOperator @operator)
            : this(null, @operator, null)
        { }
        public MySqlBoolean(IEvaluatable left, MySqlBooleanOperator @operator, IEvaluatable right)
        {
            if (left is IQuery)
                (left as IQuery).IsSubQuery = true;
            if (right is IQuery)
                (right as IQuery).IsSubQuery = true;

            Left = left;
            Right = right;
            _operator = @operator;
        }
        #endregion

        #region IExpression Members

        public IEvaluatable Left
        {
            get { return _left; }
            set 
            { 
                _left = value;
            }
        }

        public IEvaluatable Right
        {
            get { return _right; }
            set 
            { 
                _right = value;
            }
        }

        #endregion

        #region IRelationalElement Members

        public string ToSql()
        {
            StringBuilder builder = new StringBuilder();
            builder.Append(_left.ToSql());
            switch (_operator)
            {
                case MySqlBooleanOperator.Equal:
                    builder.Append("=");
                    break;
                case MySqlBooleanOperator.NotEqual:
                    builder.Append("<>");
                    break;
                case MySqlBooleanOperator.GreaterThan:
                    builder.Append(">");
                    break;
                case MySqlBooleanOperator.GreaterThanOrEqual:
                    builder.Append(">=");
                    break;
                case MySqlBooleanOperator.LessThan:
                    builder.Append("<");
                    break;
                case MySqlBooleanOperator.LessThanOrEqual:
                    builder.Append("<=");
                    break;
                case MySqlBooleanOperator.Like:
                    builder.Append(" LIKE ");
                    break;
                case MySqlBooleanOperator.NotLike:
                    builder.Append(" NOT LIKE ");
                    break;
                case MySqlBooleanOperator.And:
                    builder.Append(" AND ");
                    break;
                case MySqlBooleanOperator.Or:
                    builder.Append(" OR ");
                    break;
                case MySqlBooleanOperator.In:
                    builder.Append(" IN ");
                    break;
                case MySqlBooleanOperator.NotIn:
                    builder.Append(" NOT IN ");
                    break;
            }
            builder.Append(_right.ToSql());

            return "(" + builder.ToString() + ")";
        }


        #endregion

        #region Operator overloads
        public static MySqlBoolean operator &(MySqlBoolean left, IExpression right)
        {
            return new MySqlAnd(left, right);
        }
        public static MySqlBoolean operator |(MySqlBoolean left, IExpression right)
        {
            return new MySqlOr(left, right);
        } 
        #endregion
    }
}
